<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MongoDB架构设计与最佳实践</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-self;
            background-color: #f8fafc;
            color: #1e293b;
        }
        .hero {
            background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 100%);
        }
        .code-block {
            background-color: #1e293b;
            border-left: 4px solid #3b82f6;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .section-divider {
            position: relative;
            height: 80px;
            overflow: hidden;
        }
        .section-divider::before {
            content: "";
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            height: 100%;
            background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%);
            clip-path: polygon(0 0, 100% 0, 100% 50%, 0 100%);
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:py-32">
        <div class="container mx-auto max-w-5xl">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-2/3">
                    <h1 class="text-4xl md:text-5xl font-bold mb-4 leading-tight">MongoDB架构设计与最佳实践</h1>
                    <p class="text-xl md:text-2xl text-blue-100 mb-8">构建高可用、可扩展的数据库解决方案</p>
                    <div class="flex items-center space-x-4">
                        <span class="bg-blue-500 text-white px-4 py-2 rounded-full text-sm font-semibold">复制集架构</span>
                        <span class="bg-blue-500 text-white px-4 py-2 rounded-full text-sm font-semibold">分片集群</span>
                        <span class="bg-blue-500 text-white px-4 py-2 rounded-full text-sm font-semibold">数据建模</span>
                    </div>
                </div>
                <div class="hidden md:block md:w-1/3">
                    <div class="relative">
                        <div class="absolute -right-10 -top-10 w-64 h-64 bg-blue-400 rounded-full opacity-20"></div>
                        <div class="absolute -right-5 -top-5 w-64 h-64 bg-blue-500 rounded-full opacity-20"></div>
                        <div class="relative w-64 h-64 bg-white bg-opacity-10 rounded-2xl backdrop-blur-sm border border-blue-300 border-opacity-30 flex items-center justify-center">
                            <i class="fas fa-database text-6xl text-white opacity-80"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="container mx-auto max-w-5xl px-4 py-12">
        <!-- 1. 复制集架构设计与实现 -->
        <section id="replica-set" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="bg-blue-100 text-blue-800 w-12 h-12 rounded-full flex items-center justify-center mr-4">
                    <span class="text-xl font-bold">01</span>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">复制集架构设计与实现</h2>
            </div>

            <!-- 1.1 复制集概念与工作原理 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">复制集概念与工作原理</h3>
                <p class="text-gray-700 mb-6 leading-relaxed">复制集是MongoDB的高可用性解决方案，通过维护多个数据副本来确保数据的可用性和可靠性。</p>
                
                <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
                    <div class="bg-white rounded-xl shadow-md p-6 card-hover transition-all duration-300">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-crown text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">主节点（Primary）</h4>
                        <p class="text-gray-600">处理所有写操作，维护oplog日志，自动故障转移</p>
                    </div>
                    <div class="bg-white rounded-xl shadow-md p-6 card-hover transition-all duration-300">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-copy text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">从节点（Secondary）</h4>
                        <p class="text-gray-600">复制主节点数据，可以处理读操作，可成为新主节点</p>
                    </div>
                    <div class="bg-white rounded-xl shadow-md p-6 card-hover transition-all duration-300">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-balance-scale text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">仲裁节点（Arbiter）</h4>
                        <p class="text-gray-600">参与选举投票但不存储数据，降低部署成本</p>
                    </div>
                </div>

                <div class="bg-gray-50 p-6 rounded-xl mb-8">
                    <h4 class="font-semibold text-lg mb-4 text-gray-800">复制集工作原理可视化</h4>
                    <div class="mermaid">
                        graph TD
                            A[Primary] -->|写入数据| B(Secondary 1)
                            A -->|写入数据| C(Secondary 2)
                            A -->|选举投票| D[Arbiter]
                            B -->|故障转移| A
                            C -->|故障转移| A
                    </div>
                </div>
            </div>

            <!-- 1.2 复制集成员角色详解 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">复制集成员角色详解</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <h4 class="font-bold text-lg mb-3 text-blue-700 flex items-center">
                            <i class="fas fa-crown mr-2"></i> Primary节点
                        </h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>处理所有写操作</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>处理所有读操作（默认）</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>维护oplog日志</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>自动故障转移</span>
                            </li>
                        </ul>
                    </div>
                    
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <h4 class="font-bold text-lg mb-3 text-blue-700 flex items-center">
                            <i class="fas fa-copy mr-2"></i> Secondary节点
                        </h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>复制主节点数据</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>可以处理读操作</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>可以成为新的主节点</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>可以配置为延迟复制</span>
                            </li>
                        </ul>
                    </div>
                    
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <h4 class="font-bold text-lg mb-3 text-blue-700 flex items-center">
                            <i class="fas fa-balance-scale mr-2"></i> Arbiter节点
                        </h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>不存储数据</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>参与选举投票</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                                <span>降低部署成本</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- 1.3 选举机制与故障转移 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">选举机制与故障转移</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-6">
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">复制集配置示例</h4>
                        <div class="code-block rounded-lg p-4 mb-6 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>// 配置复制集
rs.initiate({
    _id: "rs0",
    members: [
        { _id: 0, host: "mongodb1:27017" },
        { _id: 1, host: "mongodb2:27017" },
        { _id: 2, host: "mongodb3:27017", arbiterOnly: true }
    ]
})

// 查看复制集状态
rs.status()</code></pre>
                        </div>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">选举触发条件</h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-bolt text-yellow-500 mt-1 mr-2"></i>
                                <span>主节点不可达超过选举超时时间（默认为10秒）</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-bolt text-yellow-500 mt-1 mr-2"></i>
                                <span>主节点主动降级（如执行rs.stepDown()）</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-bolt text-yellow-500 mt-1 mr-2"></i>
                                <span>向复制集中添加新节点</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-bolt text-yellow-500 mt-1 mr-2"></i>
                                <span>初始化复制集</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- 1.4 读写分离实现 -->
            <div>
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">读写分离实现</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">代码配置示例</h4>
                        <div class="code-block rounded-lg p-4 mb-6 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>// 配置读偏好
db.getMongo().setReadPref('secondary')

// 在连接字符串中配置
mongodb://mongodb1:27017,mongodb2:27017/?replicaSet=rs0&readPreference=secondary</code></pre>
                        </div>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">读偏好模式</h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-book-reader text-purple-500 mt-1 mr-2"></i>
                                <span><strong>primary</strong> - 默认，所有读操作到主节点</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-book-reader text-purple-500 mt-1 mr-2"></i>
                                <span><strong>primaryPreferred</strong> - 优先主节点，不可用时从从节点读取</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-book-reader text-purple-500 mt-1 mr-2"></i>
                                <span><strong>secondary</strong> - 所有读操作到从节点</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-book-reader text-purple-500 mt-1 mr-2"></i>
                                <span><strong>secondaryPreferred</strong> - 优先从节点，不可用时从主节点读取</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-book-reader text-purple-500 mt-1 mr-2"></i>
                                <span><strong>nearest</strong> - 从网络延迟最低的节点读取</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Section Divider -->
        <div class="section-divider my-12"></div>

        <!-- 2. 分片集群详解 -->
        <section id="sharding" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="bg-blue-100 text-blue-800 w-12 h-12 rounded-full flex items-center justify-center mr-4">
                    <span class="text-xl font-bold">02</span>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">分片集群详解</h2>
            </div>

            <!-- 2.1 分片集群架构组件 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">分片集群架构组件</h3>
                
                <div class="bg-gray-50 p-6 rounded-xl mb-8">
                    <div class="mermaid">
                        graph TD
                            Client -->|查询请求| Mongos
                            Mongos -->|路由请求| ConfigServer[(Config Server)]
                            Mongos -->|数据操作| Shard1[Shard 1]
                            Mongos -->|数据操作| Shard2[Shard 2]
                            Mongos -->|数据操作| Shard3[Shard 3]
                            Shard1 -->|复制集| RS1-1[Primary]
                            Shard1 -->|复制集| RS1-2[Secondary]
                            Shard1 -->|复制集| RS1-3[Secondary]
                    </div>
                </div>
                
                <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-cubes text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">分片（Shard）</h4>
                        <p class="text-gray-600">存储数据的节点，通常是复制集架构，确保高可用性</p>
                    </div>
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-server text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">配置服务器（Config Server）</h4>
                        <p class="text-gray-600">存储集群元数据，如分片键、数据分布等信息</p>
                    </div>
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-route text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">路由服务器（mongos）</h4>
                        <p class="text-gray-600">处理客户端请求，路由到正确的分片</p>
                    </div>
                </div>
            </div>

            <!-- 2.2 分片键选择策略 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">分片键选择策略</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-6">
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">代码配置示例</h4>
                        <div class="code-block rounded-lg p-4 mb-6 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>// 启用分片
sh.enableSharding("mydb")

// 选择分片键
sh.shardCollection("mydb.users", { "userId": "hashed" })</code></pre>
                        </div>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">分片键选择考虑因素</h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-project-diagram text-green-500 mt-1 mr-2"></i>
                                <span><strong>基数（Cardinality）</strong> - 分片键值的唯一性程度</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-project-diagram text-green-500 mt-1 mr-2"></i>
                                <span><strong>写分布</strong> - 确保写入能均匀分布到各个分片</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-project-diagram text-green-500 mt-1 mr-2"></i>
                                <span><strong>查询模式</strong> - 查询是否包含分片键</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-project-diagram text-green-500 mt-1 mr-2"></i>
                                <span><strong>数据增长</strong> - 分片键是否随数据增长而单调递增</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- 2.3 数据分布方式 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">数据分布方式</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">范围分片 (Range Sharding)</h4>
                        <div class="code-block rounded-lg p-4 mb-6 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>sh.shardCollection("mydb.users", { "age": 1 })</code></pre>
                        </div>
                        <p class="text-gray-700 mb-4">根据分片键值的范围将数据分配到不同的分片。适用于:</p>
                        <ul class="text-gray-700 space-y-2 list-disc list-inside">
                            <li>范围查询频繁的场景</li>
                            <li>分片键值分布均匀的情况</li>
                        </ul>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">哈希分片 (Hashed Sharding)</h4>
                        <div class="code-block rounded-lg p-4 mb-6 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>sh.shardCollection("mydb.users", { "userId": "hashed" })</code></pre>
                        </div>
                        <p class="text-gray-700 mb-4">对分片键值进行哈希计算后分配数据。适用于:</p>
                        <ul class="text-gray-700 space-y-2 list-disc list-inside">
                            <li>写操作频繁的场景</li>
                            <li>分片键值单调递增的情况</li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- 2.4 分片集群管理 -->
            <div>
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">分片集群管理</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">常用管理命令</h4>
                        <div class="code-block rounded-lg p-4 mb-6 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>// 添加分片
sh.addShard("mongodb1:27017")

// 查看分片状态
sh.status()

// 平衡器操作
sh.startBalancer()
sh.stopBalancer()</code></pre>
                        </div>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">监控指标</h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-chart-line text-blue-500 mt-1 mr-2"></i>
                                <span><strong>分片均衡状态</strong> - 检查数据是否均匀分布</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-chart-line text-blue-500 mt-1 mr-2"></i>
                                <span><strong>分片查询路由</strong> - 检查查询是否高效路由</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-chart-line text-blue-500 mt-1 mr-2"></i>
                                <span><strong>分片性能</strong> - 监控各分片的负载情况</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-chart-line text-blue-500 mt-1 mr-2"></i>
                                <span><strong>块迁移</strong> - 监控数据块的迁移状态</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Section Divider -->
        <div class="section-divider my-12"></div>

        <!-- 3. 数据建模最佳实践 -->
        <section id="data-modeling" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="bg-blue-100 text-blue-800 w-12 h-12 rounded-full flex items-center justify-center mr-4">
                    <span class="text-xl font-bold">03</span>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">数据建模最佳实践</h2>
            </div>

            <!-- 3.1 文档模型设计原则 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">文档模型设计原则</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
                    <div class="bg-white rounded-xl shadow-md p-6 text-center">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-laptop-code text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">应用需求</h4>
                        <p class="text-gray-600 text-sm">优先考虑应用查询和更新模式</p>
                    </div>
                    <div class="bg-white rounded-xl shadow-md p-6 text-center">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-search text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">数据访问</h4>
                        <p class="text-gray-600 text-sm">考虑数据访问模式</p>
                    </div>
                    <div class="bg-white rounded-xl shadow-md p-6 text-center">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-chart-line text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">数据增长</h4>
                        <p class="text-gray-600 text-sm">考虑数据增长模式</p>
                    </div>
                    <div class="bg-white rounded-xl shadow-md p-6 text-center">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-tachometer-alt text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">查询性能</h4>
                        <p class="text-gray-600 text-sm">考虑查询性能需求</p>
                    </div>
                </div>
            </div>

            <!-- 3.2 关系建模模式 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">关系建模模式</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-3 gap-8 mb-8">
                    <!-- 一对一关系 -->
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <h4 class="font-bold text-lg mb-3 text-blue-700">一对一关系</h4>
                        
                        <div class="mb-4">
                            <h5 class="font-semibold text-gray-700 mb-2">内嵌文档方式</h5>
                            <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                                <pre><code>{
    _id: ObjectId(),
    name: "张三",
    address: {
        city: "北京",
        street: "朝阳区"
    }
}</code></pre>
                            </div>
                        </div>
                        
                        <div>
                            <h5 class="font-semibold text-gray-700 mb-2">引用方式</h5>
                            <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                                <pre><code>{
    _id: ObjectId(),
    name: "张三",
    address_id: ObjectId("...")
}</code></pre>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 一对多关系 -->
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <h4 class="font-bold text-lg mb-3 text-blue-700">一对多关系</h4>
                        
                        <div class="mb-4">
                            <h5 class="font-semibold text-gray-700 mb-2">内嵌数组方式</h5>
                            <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                                <pre><code>{
    _id: ObjectId(),
    name: "张三",
    orders: [
        { order_id: "001", amount: 100 },
        { order_id: "002", amount: 200 }
    ]
}</code></pre>
                            </div>
                        </div>
                        
                        <div>
                            <h5 class="font-semibold text-gray-700 mb-2">引用方式</h5>
                            <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                                <pre><code>// 在users集合中
{
    _id: ObjectId(),
    name: "张三"
}

// 在orders集合中
{
    _id: ObjectId(),
    user_id: ObjectId("..."),
    amount: 100
}</code></pre>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 多对多关系 -->
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <h4 class="font-bold text-lg mb-3 text-blue-700">多对多关系</h4>
                        
                        <div>
                            <h5 class="font-semibold text-gray-700 mb-2">使用引用数组</h5>
                            <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                                <pre><code>{
    _id: ObjectId(),
    name: "张三",
    roles: [ObjectId("..."), ObjectId("...")]
}</code></pre>
                            </div>
                        </div>
                        
                        <div class="mt-4 p-3 bg-blue-50 rounded-lg">
                            <p class="text-sm text-blue-700">多对多关系通常需要使用两个集合：</p>
                            <ol class="text-sm text-blue-700 list-decimal list-inside mt-1">
                                <li>用户集合</li>
                                <li>角色集合</li>
                                <li>用户-角色关联集合（可选）</li>
                            </ol>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 3.3 常见设计模式 -->
            <div>
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">常见设计模式</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <h4 class="font-bold text-lg mb-3 text-blue-700">树形结构</h4>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>// 父引用模式
{
    _id: ObjectId("..."),
    name: "root",
    parent_id: null
}

// 子引用模式
{
    _id: ObjectId("..."),
    name: "root",
    children: [ObjectId("..."), ObjectId("...")]
}

// 路径枚举模式
{
    _id: ObjectId("..."),
    name: "node",
    path: "root,child,grandchild"
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="bg-white rounded-xl shadow-md p-6">
                        <h4 class="font-bold text-lg mb-3 text-blue-700">其他模式</h4>
                        
                        <div class="mb-4">
                            <h5 class="font-semibold text-gray-700 mb-2">预聚合</h5>
                            <p class="text-gray-600 text-sm mb-2">预先计算并存储聚合结果，提高查询性能</p>
                            <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                                <pre><code>{
    _id: "user_stats",
    user_id: ObjectId("..."),
    total_orders: 10,
    total_amount: 1000
}</code></pre>
                            </div>
                        </div>
                        
                        <div>
                            <h5 class="font-semibold text-gray-700 mb-2">分桶</h5>
                            <p class="text-gray-600 text-sm mb-2">将数据分组存储以减少文档数量</p>
                            <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                                <pre><code>{
    _id: "sensor_202101",
    sensor_id: 1,
    month: "2021-01",
    readings: [
        { time: ISODate("..."), value: 10 },
        { time: ISODate("..."), value: 12 }
    ]
}</code></pre>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Section Divider -->
        <div class="section-divider my-12"></div>

        <!-- 4. 安全架构与访问控制 -->
        <section id="security">
            <div class="flex items-center mb-8">
                <div class="bg-blue-100 text-blue-800 w-12 h-12 rounded-full flex items-center justify-center mr-4">
                    <span class="text-xl font-bold">04</span>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">安全架构与访问控制</h2>
            </div>

            <!-- 4.1 认证机制 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">认证机制</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-6">
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">用户创建示例</h4>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>// 创建管理员用户
db.createUser({
    user: "admin",
    pwd: "password",
    roles: ["userAdminAnyDatabase"]
})

// 创建应用用户
db.createUser({
    user: "app",
    pwd: "password",
    roles: [
        { role: "readWrite", db: "mydb" }
    ]
})</code></pre>
                        </div>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">认证方式</h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-user-shield text-blue-500 mt-1 mr-2"></i>
                                <span><strong>SCRAM-SHA-1/256</strong> - 默认的密码认证机制</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-user-shield text-blue-500 mt-1 mr-2"></i>
                                <span><strong>x.509证书认证</strong> - 使用TLS证书进行认证</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-user-shield text-blue-500 mt-1 mr-2"></i>
                                <span><strong>LDAP认证</strong> - 集成企业LDAP</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-user-shield text-blue-500 mt-1 mr-2"></i>
                                <span><strong>Kerberos认证</strong> - 企业级认证</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- 4.2 基于角色的访问控制 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">基于角色的访问控制</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">内置角色</h4>
                        <div class="grid grid-cols-1 gap-4">
                            <div class="bg-white rounded-lg p-4 shadow-sm">
                                <h5 class="font-semibold text-blue-700 mb-2">数据库用户角色</h5>
                                <ul class="text-gray-700 text-sm space-y-1">
                                    <li><span class="font-medium">read</span> - 只读权限</li>
                                    <li><span class="font-medium">readWrite</span> - 读写权限</li>
                                </ul>
                            </div>
                            <div class="bg-white rounded-lg p-4 shadow-sm">
                                <h5 class="font-semibold text-blue-700 mb-2">数据库管理角色</h5>
                                <ul class="text-gray-700 text-sm space-y-1">
                                    <li><span class="font-medium">dbAdmin</span> - 数据库管理</li>
                                    <li><span class="font-medium">userAdmin</span> - 用户管理</li>
                                </ul>
                            </div>
                            <div class="bg-white rounded-lg p-4 shadow-sm">
                                <h5 class="font-semibold text-blue-700 mb-2">集群管理角色</h5>
                                <ul class="text-gray-700 text-sm space-y-1">
                                    <li><span class="font-medium">clusterAdmin</span> - 集群管理</li>
                                    <li><span class="font-medium">clusterManager</span> - 集群监控</li>
                                </ul>
                            </div>
                        </div>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">自定义角色</h4>
                        <div class="code-block rounded-lg p-4 mb-6 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code>db.createRole({
    role: "appRole",
    privileges: [
        {
            resource: { db: "mydb", collection: "users" },
            actions: [ "find", "update" ]
        }
    ],
    roles: []
})</code></pre>
                        </div>
                        <h5 class="font-semibold text-gray-700 mb-2">权限操作类型</h5>
                        <ul class="text-gray-700 text-sm space-y-1">
                            <li><span class="font-medium">find</span> - 查询文档</li>
                            <li><span class="font-medium">insert</span> - 插入文档</li>
                            <li><span class="font-medium">update</span> - 更新文档</li>
                            <li><span class="font-medium">delete</span> - 删除文档</li>
                            <li><span class="font-medium">createIndex</span> - 创建索引</li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- 4.3 传输加密 -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">传输加密</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
                    <div>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code># mongod.conf
net:
  ssl:
    mode: requireSSL
    PEMKeyFile: /path/to/mongodb.pem
    CAFile: /path/to/ca.pem</code></pre>
                        </div>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">TLS/SSL配置要点</h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-lock text-green-500 mt-1 mr-2"></i>
                                <span>使用有效的证书颁发机构签发的证书</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-lock text-green-500 mt-1 mr-2"></i>
                                <span>禁用旧版协议（如SSLv3）</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-lock text-green-500 mt-1 mr-2"></i>
                                <span>配置强密码套件</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-lock text-green-500 mt-1 mr-2"></i>
                                <span>定期轮换证书</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- 4.4 存储加密 -->
            <div>
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-2 border-gray-200">存储加密</h3>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
                    <div>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm overflow-x-auto">
                            <pre><code># mongod.conf
security:
  encryption:
    keyFile: /path/to/keyfile</code></pre>
                        </div>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-3 text-gray-800">存储加密选项</h4>
                        <ul class="text-gray-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-key text-purple-500 mt-1 mr-2"></i>
                                <span><strong>文件系统加密</strong> - 依赖底层文件系统加密</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-key text-purple-500 mt-1 mr-2"></i>
                                <span><strong>加密存储引擎</strong> - MongoDB企业版特性</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-key text-purple-500 mt-1 mr-2"></i>
                                <span><strong>应用层加密</strong> - 应用端加密敏感数据</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-key text-purple-500 mt-1 mr-2"></i>
                                <span><strong>字段级加密</strong> - MongoDB 4.2+企业版</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            },
            themeVariables: {
                primaryColor: '#E3F2FD',
                primaryBorderColor: '#90CAF9',
                primaryTextColor: '#1E293B',
                lineColor: '#4B5563',
                secondaryColor: '#DBEAFE',
                tertiaryColor: '#BFDBFE'
            }
        });
    </script>
</body>
</html>